package com.oocl.scan.global;

import com.oocl.scan.db.ArangoDBConnection;
import com.oocl.scan.handler.AjaxCallHandler;
import com.oocl.scan.handler.ConstantVariableHandler;
import com.oocl.scan.handler.DaoAndModelHandler;
import com.oocl.scan.handler.GlobalObjectHandler;
import com.oocl.scan.handler.Handler;
import com.oocl.scan.handler.JavaClassHandler;
import com.oocl.scan.handler.ModelHandler;
import com.oocl.scan.handler.SoapConfigHandler;
import com.oocl.scan.io.FileScanner;
import com.oocl.scan.model.JavaClassElement;
import com.oocl.scan.producer.ElementProducer;
import com.oocl.scan.producer.SoapConfigProducer;
import com.oocl.scan.store.ComponentStore;
import com.oocl.scan.store.JavaClassStore;
import com.oocl.scan.store.RelationshipStore;
import com.oocl.scan.store.SoapConfigStore;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class InitComponent {

  private ExecutorService threadPool = Executors.newFixedThreadPool(10);

  public void init(String filePath) {
    initJavaElementStore(filePath);
    initComponent(Arrays.asList(new JavaClassHandler(), new ModelHandler(), new SoapConfigHandler(), new GlobalObjectHandler()));
    initComponent(Arrays.asList(new AjaxCallHandler(), new DaoAndModelHandler(), new ConstantVariableHandler()));
    shutdown();
  }

  private void initJavaElementStore(String filePath) {
    FileScanner scanner = new FileScanner(Arrays.asList(new ElementProducer(), new SoapConfigProducer()));
    scanner.scan(filePath);
    SoapConfigStore.getInstance().saveSoapConfig();
  }

  private void initComponent(List<Handler> handlers) {
    List<Handler> handlerList = handlers;
    for (Object object : JavaClassStore.getInstance().getQueue()) {
      threadPool.execute(new Runnable() {
        @Override
        public void run() {
          for (Handler handler : handlerList) {
            handler.handle((JavaClassElement) object);
          }
        }
      });
    }
  }

  private void saveToDB() {
    ComponentStore.getInstance().saveComponent();
    RelationshipStore.getInstance().saveRelationship();
  }

  private void shutdown() {
    threadPool.shutdown();
    while (true) {
      if (threadPool.isTerminated()) {
        saveToDB();
        break;
      }
    }
    ArangoDBConnection.shutdown();
  }
}
